load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "int_flag")
load("@cmake_configure_file//:cmake_configure_file.bzl", "cmake_configure_file")
load("@rules_cc//cc:defs.bzl", "cc_library")

package(default_visibility = ["//visibility:public"])

config_setting(
    name = "is_building_debug",
    values = {"compilation_mode": "dbg"},
)

bool_flag(
    name = "pcl_silence_malloc_warning",
    build_setting_default = False,
)

config_setting(
    name = "pcl_malloc_no_warns",
    flag_values = {":pcl_silence_malloc_warning": "True"},
)

# Set via --@pcl//:pcl_index_signed=True on command line, bazelrc, or in a transition
# https://github.com/PointCloudLibrary/pcl/blob/pcl-1.15.0/cmake/pcl_options.cmake#L110-L116
bool_flag(
    name = "pcl_index_signed",
    build_setting_default = True,
)

config_setting(
    name = "pcl_index_is_signed",
    flag_values = {":pcl_index_signed": "True"},
)

# Set via --@pcl//:pcl_index_size=N on command line, bazelrc, or in a transition
# Available options are: 8 16 32 64. A negative value indicates default size (32)
# https://github.com/PointCloudLibrary/pcl/blob/pcl-1.15.0/cmake/pcl_options.cmake#L106-L108
int_flag(
    name = "pcl_index_size",
    build_setting_default = -1,
    make_variable = "PCL_INDEX_SIZE",
)

cmake_configure_file(
    name = "pcl_config_header",
    src = "pcl_config.h.in",
    out = "pcl_config.h",
    cmakelists = ["CMakeLists.txt"],
    defines = [
        "HAVE_QHULL",
        "PCL_PREFER_BOOST_FILESYSTEM",
        "PCL_INDEX_SIZE=$(PCL_INDEX_SIZE)",
        "PCL_DEV_VERSION=1",
        "PCL_VERSION_MAJOR=" + module_version().split(".")[0],
        "PCL_VERSION_MINOR=" + module_version().split(".")[1],
        "PCL_VERSION_PATCH=" + module_version().split(".")[2],
        "PCL_VERSION_PRETTY=" + module_version(),
        "PROJECT_NAME=" + module_name(),
        "VTK_RENDERING_BACKEND_OPENGL_VERSION=2",
        "PCL_NORMAL_POINT_TYPES=(pcl::Normal)(pcl::PointNormal)(pcl::PointXYZRGBNormal)(pcl::PointXYZINormal)(pcl::PointXYZLNormal)(pcl::PointSurfel)",
        "PCL_XYZ_POINT_TYPES=(pcl::PointXYZ)(pcl::PointXYZI)(pcl::PointXYZL)(pcl::PointXYZRGBA)(pcl::PointXYZRGB)(pcl::PointXYZRGBL)(pcl::PointXYZLAB)(pcl::PointXYZHSV)(pcl::InterestPoint)(pcl::PointNormal)(pcl::PointXYZRGBNormal)(pcl::PointXYZINormal)(pcl::PointXYZLNormal)(pcl::PointWithRange)(pcl::PointWithViewpoint)(pcl::PointWithScale)(pcl::PointSurfel)(pcl::PointDEM)",
    ] + select({
        "//:is_building_debug": ["CMAKE_BUILD_TYPE=Debug"],
        "//conditions:default": ["CMAKE_BUILD_TYPE=Release"],
    }) + select({
        ":pcl_index_is_signed": ["PCL_INDEX_SIGNED_STR=true"],
        "//conditions:default": ["PCL_INDEX_SIGNED_STR=false"],
    }) + select({
        ":pcl_malloc_no_warns": ["PCL_SILENCE_MALLOC_WARNING"],
        "//conditions:default": [],
    }),
    toolchains = [":pcl_index_size"],
    undefines = ["HAVE_CJSON"],
    visibility = ["//visibility:private"],
)

cc_library(
    name = "pcl_config",
    hdrs = [":pcl_config.h"],
    include_prefix = "pcl",
)

cc_library(
    name = "2d",
    srcs = ["2d/src/convolution_2d.cpp"] + glob(["2d/include/pcl/**/impl/*.hpp"]),
    hdrs = glob(["2d/include/**/*.h"]),
    includes = ["2d/include"],
    deps = [
        ":common",
        ":filters",
    ],
)

cc_library(
    name = "common",
    srcs = glob([
        "common/src/fft/*.c",
        "common/src/**/*.cpp",
        "common/include/pcl/**/impl/*.hpp",
    ]),
    hdrs = glob(["common/include/**/*.h"]),
    includes = ["common/include"],
    deps = [
        ":pcl_config",
        "@boost.algorithm",
        "@boost.assert",
        "@boost.filesystem",
        "@boost.fusion",
        "@boost.mpl",
        "@boost.predef",
        "@boost.preprocessor",
        "@boost.signals2",
        "@eigen",
    ],
)

cc_library(
    name = "features",
    srcs = glob([
        "features/src/*.cpp",
        "features/include/pcl/features/impl/*.hpp",
    ]),
    hdrs = glob(["features/include/pcl/features/*.h"]),
    includes = ["features/include"],
    deps = [
        ":2d",
        ":common",
        ":filters",
        ":kdtree",
        ":octree",
        ":search",
        "@boost.graph",
        "@boost.property_map",
        "@eigen",
    ],
)

cc_library(
    name = "filters",
    srcs = glob([
        "filters/src/*.cpp",
        "filters/include/pcl/filters/impl/*.hpp",
    ]),
    hdrs = glob(["filters/include/**/*.h"]),
    includes = ["filters/include"],
    deps = [
        ":common",
        ":kdtree",
        ":octree",
        ":pcl_config",
        ":sample_consensus",
        ":search",
        "@boost.dynamic_bitset",
        "@boost.fusion",
        "@boost.mpl",
        "@boost.optional",
        "@boost.random",
        "@boost.sort",
        "@eigen",
    ],
)

cc_library(
    name = "geometry",
    srcs = glob(["geometry/include/pcl/geometry/impl/*.hpp"]),
    hdrs = glob(["geometry/include/pcl/geometry/*.h"]),
    includes = ["geometry/include"],
    deps = [
        ":common",
        "@boost.config",
        "@boost.utility",
        "@eigen",
    ],
)

# TODO: add "gpu" subsystems

cc_library(
    name = "io",
    srcs = glob(
        [
            "io/src/**/*.cpp",
            "io/include/pcl/*/impl/*.hpp",
        ],
        exclude = [
            "io/src/davidsdk_grabber.cpp",
            "io/src/depth_sense/*",
            "io/src/depth_sense*",
            "io/src/dinast_grabber.cpp",
            "io/src/ensenso_grabber.cpp",
            "io/src/oni_grabber.cpp",
            "io/src/openni2/*",
            "io/src/openni_camera/*",
            "io/src/real_sense/*",
            "io/src/real_sense*",
            "io/src/png_io.cpp",
            "io/src/vtk_lib_io.cpp",
        ],
    ),
    hdrs = glob(
        ["io/include/**/*.h"],
        exclude = [
            "io/include/pcl/io/davidsdk_grabber.h",
            "io/include/pcl/io/depth_sense/*",
            "io/include/pcl/io/depth_sense*",
            "io/include/pcl/io/dinast_grabber.h",
            "io/include/pcl/io/ensenso_grabber.h",
            "io/include/pcl/io/oni_grabber.h",
            "io/include/pcl/io/openni2/*",
            "io/include/pcl/io/openni_camera/*",
            "io/include/pcl/io/real_sense/*",
            "io/include/pcl/io/real_sense*",
            "io/include/pcl/io/impl/vtk_lib_io.hpp",
            "io/include/pcl/io/png_io.h",
            "io/include/pcl/io/vtk_lib_io.h",
        ],
    ),
    includes = ["io/include"],
    deps = [
        ":common",
        ":octree",
        ":pcl_config",
        "@boost.algorithm",
        "@boost.array",
        "@boost.asio",
        "@boost.circular_buffer",
        "@boost.core",
        "@boost.filesystem",
        "@boost.foreach",
        "@boost.format",
        "@boost.interprocess",
        "@boost.iostreams",
        "@boost.lexical_cast",
        "@boost.math",
        "@boost.mpl",
        "@boost.multiprecision",
        "@boost.numeric_conversion",
        "@boost.predef",
        "@boost.property_tree",
        "@boost.signals2",
        "@boost.smart_ptr",
        "@boost.tokenizer",
        "@boost.utility",
        "@libpng",
    ],
)

cc_library(
    name = "kdtree",
    srcs = ["kdtree/src/kdtree_flann.cpp"] + glob(["kdtree/include/pcl/kdtree/impl/*.hpp"]),
    hdrs = glob(["kdtree/include/pcl/kdtree/*.h"]),
    includes = ["kdtree/include"],
    deps = [
        ":common",
        "@flann//:flann_cpp",
    ],
)

cc_library(
    name = "keypoints",
    srcs = glob([
        "keypoints/src/*.cpp",
        "keypoints/include/pcl/keypoints/impl/*.hpp",
    ]),
    hdrs = glob(["keypoints/include/pcl/keypoints/*.h"]),
    includes = ["keypoints/include"],
    deps = [
        ":common",
        ":features",
        ":filters",
        ":octree",
        ":pcl_config",
        ":search",
        "@eigen",
    ],
)

cc_library(
    name = "ml",
    srcs = glob([
        "ml/src/**/*.cpp",
        "ml/include/pcl/ml/impl/**/*.hpp",
    ]),
    hdrs = glob(["ml/include/**/*.h"]),
    includes = ["ml/include"],
    deps = [":common"],
)

cc_library(
    name = "octree",
    srcs = ["octree/src/octree_inst.cpp"] + glob(["octree/include/pcl/octree/impl/*.hpp"]),
    hdrs = glob(["octree/include/pcl/octree/*.h"]),
    includes = ["octree/include"],
    deps = [
        ":common",
        "@boost.graph",
    ],
)

cc_library(
    name = "outofcore",
    srcs = glob([
        "outofcore/src/*.cpp",
        "outofcore/include/pcl/outofcore/impl/*.hpp",
    ]),
    hdrs = glob(["outofcore/include/pcl/outofcore/*.h"]),
    includes = ["outofcore/include"],
    deps = [
        ":common",
        ":filters",
        ":io",
        ":octree",
        ":visualization",
        "@boost.filesystem",
        "@boost.foreach",
        "@boost.uuid",
    ],
)

cc_library(
    name = "people",
    srcs = ["people/src/hog.cpp"] + glob(["people/include/pcl/people/impl/*.hpp"]),
    hdrs = glob(
        ["people/include/pcl/people/*.h"],
        exclude = ["include/pcl/people/person_cluster.h"],  # TODO: needs vtk
    ),
    includes = ["people/include"],
    deps = [
        ":common",
        ":filters",
        ":kdtree",
        ":sample_consensus",
        ":segmentation",
        # ":visualization",
    ],
)

cc_library(
    name = "recognition",
    srcs = glob(
        [
            "recognition/src/**/*.cpp",
            "recognition/include/pcl/recognition/impl/**/*.hpp",
        ],
        exclude = ["recognition/src/hv/hv_go.cpp"],
    ),
    hdrs = glob(
        [
            "recognition/include/**/*.h",
            "recognition/include/**/*.hh",
        ],
        exclude = ["recognition/include/pcl/recognition/hv/hv_go.h"],
    ),
    includes = ["recognition/include"],
    deps = [
        ":common",
        ":features",
        ":filters",
        ":io",
        ":kdtree",
        ":ml",
        ":registration",
        ":search",
        "@boost.algorithm",
        "@boost.filesystem",
        "@boost.graph",
        "@boost.random",
        "@eigen",
    ],
)

cc_library(
    name = "registration",
    srcs = glob(
        [
            "registration/src/**/*.cpp",
            "registration/include/pcl/registration/impl/*.hpp",
        ],
        exclude = [
            "registration/include/pcl/registration/impl/transformation_estimation_dq.hpp",
            "registration/src/pairwise_graph_registration.cpp",
            "registration/src/transformation_estimation_dq.cpp",
        ],
    ),
    hdrs = glob(
        ["registration/include/**/*.h"],
        exclude = ["registration/include/pcl/registration/transformation_estimation_dq.h"],
    ),
    includes = ["registration/include"],
    deps = [
        ":common",
        ":features",
        ":filters",
        ":kdtree",
        ":sample_consensus",
        ":search",
        "@boost.core",
        "@boost.graph",
        "@boost.property_map",
        "@boost.smart_ptr",
        "@eigen",
    ],
)

cc_library(
    name = "sample_consensus",
    srcs = glob([
        "sample_consensus/src/**/*.cpp",
        "sample_consensus/include/pcl/sample_consensus/impl/*.hpp",
    ]),
    hdrs = glob(["sample_consensus/include/**/*.h"]),
    includes = ["sample_consensus/include"],
    deps = [
        ":common",
        ":pcl_config",
        ":search",
        "@boost.math",
        "@boost.multiprecision",
        "@boost.random",
        "@eigen",
    ],
)

cc_library(
    name = "search",
    srcs = glob([
        "search/src/**/*.cpp",
        "search/include/pcl/search/impl/*.hpp",
    ]),
    hdrs = glob(["search/include/**/*.h"]),
    includes = ["search/include"],
    deps = [
        ":common",
        ":kdtree",
        ":octree",
        "@eigen",
        "@flann//:flann_cpp",
    ],
)

cc_library(
    name = "segmentation",
    srcs = glob([
        "segmentation/src/**/*.cpp",
        "segmentation/include/pcl/segmentation/impl/*.hpp",
    ]),
    hdrs = glob(["segmentation/include/**/*.h"]),
    includes = ["segmentation/include"],
    deps = [
        ":common",
        ":features",
        ":filters",
        ":geometry",
        ":ml",
        ":octree",
        ":sample_consensus",
        ":search",
        "@boost.bimap",
        "@boost.concept_check",
        "@boost.graph",
        "@boost.multi_array",
        "@boost.ptr_container",
        "@boost.utility",
        "@eigen",
        "@flann//:flann_cpp",
    ],
)

# TODO: add "simulation" subsystem

# TODO: add "stereo" subsystem

cc_library(
    name = "surface",
    srcs = glob(
        [
            "surface/src/**/*.c",
            "surface/src/**/*.cpp",
            "surface/include/**/*.hpp",
        ],
        exclude = [
            "surface/src/3rdparty/opennurbs/*",
            "surface/src/on_nurbs/*",
            "surface/src/vtk_smoothing/*",
        ],
    ),
    hdrs = glob(
        ["surface/include/**/*.h"],
        exclude = [
            "surface/include/pcl/surface/3rdparty/opennurbs/*",
            "surface/include/pcl/surface/on_nurbs/*",
            "surface/include/pcl/surface/vtk_smoothing/*",
        ],
    ),
    includes = ["surface/include"],
    deps = [
        ":common",
        ":kdtree",
        ":octree",
        ":pcl_config",
        ":search",
        "@boost.dynamic_bitset",
        "@eigen",
        "@qhull//:libqhull_r",
    ],
)

# TODO: add "tools"

cc_library(
    name = "tracking",
    srcs = glob([
        "tracking/src/**/*.cpp",
        "tracking/include/pcl/tracking/impl/*.hpp",
    ]),
    hdrs = glob(["tracking/include/**/*.h"]),
    includes = ["tracking/include"],
    deps = [
        ":common",
        ":filters",
        ":octree",
        ":search",
    ],
)

# TODO: add more than a tiny chunk of visualization/common
cc_library(
    name = "visualization",
    srcs = [
        "visualization/include/pcl/visualization/common/impl/common.hpp",
        "visualization/src/common/common.cpp",
    ],
    hdrs = ["visualization/include/pcl/visualization/common/common.h"],
    includes = ["visualization/include"],
    deps = [
        ":common",
        "@eigen",
    ],
)
